package web

import (
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
)

type FileUploader struct {
	FileField   string
	DstPathFunc func(header *multipart.FileHeader) string
}

func (f FileUploader) Handle() HandleFunc {
	return func(ctx *Context) {
		file, header, err := ctx.Req.FormFile(f.FileField)
		if err != nil {
			ctx.RespStatusCode = http.StatusInternalServerError
			ctx.RespData = []byte(fmt.Sprintf("upload failed %s", err.Error()))
			return
		}
		dst := f.DstPathFunc(header)
		dstFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o666)
		if err != nil {
			ctx.RespStatusCode = http.StatusInternalServerError
			ctx.RespData = []byte(fmt.Sprintf("upload failed %s", err.Error()))
			return
		}
		_, err = io.CopyBuffer(dstFile, file, nil)
		if err != nil {
			ctx.RespStatusCode = http.StatusInternalServerError
			ctx.RespData = []byte(fmt.Sprintf("upload failed %s", err.Error()))
			return
		}
		ctx.RespStatusCode = http.StatusOK
		ctx.RespData = []byte("upload success!")
		return
	}
}

type FileDownloader struct {
	Dir string
}

func (f *FileDownloader) Handler() HandleFunc {
	return func(ctx *Context) {
		value := ctx.QueryValue("file")
		if value.err != nil {
			ctx.RespStatusCode = http.StatusBadRequest
			ctx.RespData = []byte("can not find target file")
			return
		}
		// 服务器上文件路径 + 文件名
		dst := filepath.Join(f.Dir, value.val)
		fn := filepath.Base(dst)
		header := ctx.Resp.Header()
		header.Set("Content-Disposition", "attachment;filename="+fn)
		//header.Set("Content-Description", "")
		header.Set("Content-Type", "application/octet-stream")
		header.Set("Content-Transfer-Encoding", "binary")
		header.Set("Expires", "0")
		header.Set("Cache-Control", "must-revalidate")
		header.Set("Pragma", "public")
		http.ServeFile(ctx.Resp, ctx.Req, dst)
	}
}
